package com.cssnj.portal.utils;

import com.cssnj.portal.domain.common.GeneralConstants;
import com.cssnj.portal.domain.func.GlGnEntity;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.google.common.primitives.Chars;
import io.predictech.framework.domain.common.TreeNode;
import io.predictech.framework.domain.exception.BaseSysException;
import io.predictech.framework.utility.LogUtil;
import io.predictech.framework.utility.StringUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;

import javax.validation.constraints.NotNull;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class PortalUntil {


    public static Logger logger() {
        return LogUtil.logger(GeneralConstants.PORTAL);
    }

    /**
     * @param target
     * @return
     */
    public static boolean isEmpty(Object target) {
        if (null == target) {
            return true;
        } else {
            if (target instanceof String) {
                return 0 == ((String) target).length();
            } else if (target instanceof List) {
                return ((List) target).isEmpty();
            } else if (target instanceof Map) {
                return ((Map) target).isEmpty();
            } else if (target instanceof Set) {
                return ((Set) target).isEmpty();
            } else if (target instanceof String[]) {
                return 0 == ((String[]) target).length;
            } else {
                return false;
            }
        }
    }

    /**
     * 几种常用类型非空判断
     *
     * @param target
     * @return
     * @throws BaseSysException
     */
    public static boolean isNotEmpty(Object target) {
        return !isEmpty(target);
    }


    /**
     * 方法描述 隐藏字符串中间的字符串（使用*号）
     */
    public static String hideStr(int beforeLength, int afterLength, String cardNo) {
        if (StringUtils.isBlank(cardNo)) {
            return cardNo;
        }
        //替换字符串，当前使用“*”
        final String replaceSymbol = "*";
        final int cardLen = cardNo.length();
        StringBuffer sb = new StringBuffer();
        Chars.asList(cardNo.toCharArray()).forEach(tarStr -> {
            int strBuilderLen = sb.length();
            if (strBuilderLen < beforeLength || strBuilderLen >= (cardLen - afterLength)) {
                sb.append(tarStr);
            } else {
                sb.append(replaceSymbol);
            }
        });
        return sb.toString();
    }

    /**
     * 判断是否含有特殊字符
     *
     * @param str
     * @return true为包含，false为不包含
     */
    public static boolean isSpecialChar(String str) {
        String regEx = "[ _`~!@#$%^&*()+=|{}':;',\\[\\].<>/?~！@#￥%……&*（）——+|{}【】‘；：”“’。，、？]|\n|\r|\t";
        Pattern p = Pattern.compile(regEx);
        Matcher m = p.matcher(str);
        return m.find();
    }

    /**
     * 判断字符串真正长度
     *
     * @param value
     * @return
     */
    public static int realLength(String value) {
        AtomicInteger valueLength = new AtomicInteger();
        Chars.asList(value.toCharArray()).parallelStream().forEach(tarStr -> {
            if ((tarStr >= 0x4e00) && (tarStr <= 0x9fbb)) {
                valueLength.addAndGet(2);
            } else {
                valueLength.addAndGet(1);
            }
        });
        return valueLength.get();
    }

    /**
     * @description 对功能树进行组装 为前台tree提供支持
     * @author Arthur
     * @since 2018-9-14 15:16
     **/
    public static Map<String, Object> assFuncTree(GlGnEntity gnEntity) {
        Map<String, Object> treeMap = new HashMap<>();

        treeMap.put(TreeNode.ID.getKey(), gnEntity.getGnId());
        treeMap.put(TreeNode.TEXT.getKey(), gnEntity.getGnMc());
        treeMap.put(TreeNode.CHECKED.getKey(), false);
        treeMap.put(TreeNode.STATE.getKey(), "0".equals(gnEntity.getOpenType()) ? "closed" : "open");
        treeMap.put(TreeNode.ATTRIBUTE.getKey(), gnEntity);

        return treeMap;
    }

    /**
     * @description 将 List<Map<String,T>> 格式 list 转换为 Map<String,List> 格式    二维表横竖转换
     * @author Arthur
     * @since 2018-10-17 10:08
     **/
    @SuppressWarnings("unchecked")
    public static void castListMap2MapList(@NotNull Map<String, Object> invokeMap, @NotNull List<Map<String, Object>> invokeList) {
        if (!invokeList.isEmpty()) {
            // 循环取出key作为list key
            invokeList.get(0).keySet().forEach(tempStr -> invokeMap.put(tempStr, new ArrayList<>()));
            invokeList.forEach(map -> map.keySet().forEach(key -> {
                ((ArrayList) invokeMap.get(key)).add(map.get(key));
            }));
        }
    }

    /**
     * @description 将Map中list转换为JSON
     * @author Arthur
     * @since 2018-10-17 10:29
     **/
    public static void castMapList2JSON(@NotNull Map<String, Object> invokeMap) {
        invokeMap.keySet().forEach(key -> {
            if (invokeMap.get(key) instanceof List) {
                try {
                    invokeMap.put(key, StringUtil.getBaseObjectMapper().writeValueAsString(invokeMap.get(key)));
                } catch (JsonProcessingException e) {
                    PortalUntil.logger().error("将MAP中List转换为JSON失败 -> e : " + e.getMessage());
                }
            }
        });
    }

    /**
     * @description 将MAP中value转为List
     * @author Arthur
     * @since 2018-10-17 17:15
     **/
    public static List<String> castMapValue2List(Map<String, Object> invokeMap) {
        List<String> backList = new ArrayList<>();
        invokeMap.keySet().forEach(keyStr -> backList.add(String.valueOf(invokeMap.get(keyStr))));
        return backList;
    }
}
